查看原文
其他

为什么数组下总是从0开始呢?

码上实战 2023-01-29

这个问题有没有想过?会不会认为为何设计的如此反人类呢?

有两种比较好的说法,我们了解下:

说法一

表示范围的最佳形式,比如表示自然数序列2,3,···,12,有四种方法:

a. 2 ≤ i < 13 ,或者记作 [2, 13)

b. 1 < i ≤ 12 ,或者记作 (1, 12]

c. 2 ≤ i ≤ 12 ,或者记作 [2, 12]

d. 1 < i < 13 ,或者记作 (1, 13)

a方法是最好的,有如下原因:

1. 范围的上限减去下限等于范围内元素的个数

比如方法a中,13 - 2 = 11,而范围内刚好就有11个元素,方法也有同样的性质,但方法c和d就没有。

2. 连续的范围没有重叠

两个连续的范围我们希望可以写成“0到5”和“5到9”这样的形式。如果使用方法c,12就同时包含在 [2, 12] 和 [12, 24] 这两个范围里;类似的,使用方法d,13既不包含在 (2, 13) 里也不在 (13, 25) 里。用方法a,b就没有这样的问题。比如 [2, 13) 和 [13, 25) 是两个连续的范围,13只会包含在后一个里。

方法a比方法b好的理由:我们常常会用到有下限无上限的集合,最典型的是自然数集合。比如要表示自然数集合内的范围“0到10”, 用方法a可以写成 [0, 11) , 用方法2可以写成 (-1, 10] 。方法b的问题是形式中出现了-1这个非自然数, 用非自然数来表示一个自然数集合内的范围显然不是一个好的选择。

说法二

我们常说的数组下标最精确的意思是”偏移量“,a[0]的偏移量是0,即为首地址。a[i]的偏移量是i,寻址公式:

a[i]地址 = 首地址 + i * 数据大小

如果下标从1开始,那对应的寻址公式

a[i]地址 = 首地址 + (i-1) * 数据大小

对CPU来说,每次随机访问,就多了一次减法运算,多发一条指令,所以从0开始可以减少CPU的计算。

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存